package com.hxkj.controller;

import com.hxkj.client.service.UserCenterServiceClient;
import com.hxkj.client.service.ValidateCodeServiceClient;
import com.hxkj.domain.enums.UserExceptionEnum;
import com.hxkj.domain.po.SysUser;
import com.hxkj.domain.po.Token;
import com.hxkj.domain.result.RequestParameterDataStrcut;
import com.hxkj.service.TokenService;
import com.hxkj.utils.ValidateCodeUtil;
import com.platform.common.domain.exception.CustomException;
import com.platform.common.domain.exception.CustomMessageException;
import com.platform.common.domain.result.ResultMessageStruct;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Objects;

/**
 * created by kezhijie on 2018/8/31 10:46.
 * email to kezhijie@hxoss.com
 */
@RestController
@RequestMapping("validatecode")
public class ValidateCodeController {

    @Autowired
    private ValidateCodeServiceClient validateCodeServiceClient;
    @Autowired
    private ValidateCodeUtil validateCodeUtil;
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private TokenService tokenService;
    @Autowired
    private UserCenterServiceClient userCenterServiceClient;

    /**
     * 发送短信验证码(需要检查用户是否存在)
     * @param sysUser
     * @throws Exception
     */
    @PostMapping("/sendcode")
    public void sendCode(@ModelAttribute SysUser sysUser) throws Exception {
        ResultMessageStruct resultMessageStruct = validateCodeServiceClient.sendCode(sysUser);
        if (resultMessageStruct.getCode() == 500)
            throw new CustomMessageException(resultMessageStruct.getMessage());
        if (resultMessageStruct.getCode() != 200)
            throw new CustomException(UserExceptionEnum.getEnumByCode(resultMessageStruct.getCode()));
    }

    /**
     * 发送短信验证码（不需要检查用户是否存在）
     * @param sysUser
     * @throws Exception
     */
    @PostMapping("registercode")
    public void registercode(@ModelAttribute SysUser sysUser) throws Exception {
        ResultMessageStruct resultMessageStruct = validateCodeServiceClient.registercode(sysUser);
        if (resultMessageStruct.getCode() == 500)
            throw new CustomMessageException(resultMessageStruct.getMessage());
        if (resultMessageStruct.getCode() != 200)
            throw new CustomException(UserExceptionEnum.getEnumByCode(resultMessageStruct.getCode()));
    }

    @GetMapping("getcode")
    public void getcode(HttpServletRequest request, HttpServletResponse response) throws Exception {
        validateCodeUtil.generateVerificationCode(response, request);
    }

    @PostMapping("verifyUser")
    public void verifyUser(@ModelAttribute SysUser sysUser, String code, HttpServletRequest request) throws Exception {
        if (Objects.isNull(code))
            throw new CustomException(UserExceptionEnum.REQUIRE_VALIDATECODE);
        if (Objects.isNull(sysUser) || Objects.isNull(sysUser.getUserAccount()))
            throw new CustomException(UserExceptionEnum.USERINFO_INVALID);

        Cookie[] cookies = request.getCookies();
        String storeKey = null;
        for (Cookie cookie : cookies) {
            if (cookie.getName().equals("piccode")) {
                storeKey = cookie.getValue();
                break;
            }
        }

        if (Objects.isNull(redisTemplate.boundValueOps(storeKey).get()))
            throw new CustomException(UserExceptionEnum.VALIDATECODE_INVALID);

        String varCode = redisTemplate.boundValueOps(storeKey).get().toString();
        if (! varCode.equalsIgnoreCase(code)) {
            throw new CustomException(UserExceptionEnum.VALIDATECODE_IS_ERROR);
        }

        if (StringUtils.hasText(storeKey))
            redisTemplate.delete(storeKey);

        ResultMessageStruct resultMessageStruct = validateCodeServiceClient.verifyUser(sysUser);
        if (resultMessageStruct.getCode() == 500)
            throw new CustomMessageException(resultMessageStruct.getMessage());
        if (resultMessageStruct.getCode() != 200)
            throw new CustomException(UserExceptionEnum.getEnumByCode(resultMessageStruct.getCode()));
    }

    @PostMapping("redeemByPhone")
    public void redeemByPhone(@ModelAttribute SysUser sysUser) throws Exception {
        ResultMessageStruct resultMessageStruct = validateCodeServiceClient.redeemByPhone(sysUser);

        if (resultMessageStruct.getCode() == 500)
            throw new CustomMessageException(resultMessageStruct.getMessage());
        if (resultMessageStruct.getCode() != 200)
            throw new CustomException(UserExceptionEnum.getEnumByCode(resultMessageStruct.getCode()));
    }

    @PostMapping("redeemByEmail")
    public void redeemByEmail(@ModelAttribute SysUser sysUser) throws Exception {
        ResultMessageStruct resultMessageStruct = validateCodeServiceClient.redeemByEmail(sysUser);

        if (resultMessageStruct.getCode() == 500)
            throw new CustomMessageException(resultMessageStruct.getMessage());
        if (resultMessageStruct.getCode() != 200)
            throw new CustomException(UserExceptionEnum.getEnumByCode(resultMessageStruct.getCode()));
    }

    @PostMapping("verifyCode")
    public void verifyCode(@ModelAttribute SysUser sysUser, String code, String type) throws Exception {
        RequestParameterDataStrcut<SysUser, String, String> requestParameterDataStrcut = new RequestParameterDataStrcut<>();
        requestParameterDataStrcut.setData(sysUser);
        requestParameterDataStrcut.setCode(code);
        requestParameterDataStrcut.setRequest(type);

        ResultMessageStruct resultMessageStruct = validateCodeServiceClient.verifyCode(requestParameterDataStrcut);

        if (resultMessageStruct.getCode() == 500)
            throw new CustomMessageException(resultMessageStruct.getMessage());
        if (resultMessageStruct.getCode() != 200)
            throw new CustomException(UserExceptionEnum.getEnumByCode(resultMessageStruct.getCode()));
    }

    @PostMapping("sendNewEmailVaildateCode")
    public void sendNewEmailVaildateCode(String email) throws Exception {

        if (StringUtils.isEmpty(email))
            throw new CustomException(UserExceptionEnum.USER_EMAIL_IS_NULL);

        ResultMessageStruct resultMessageStruct = validateCodeServiceClient.sendNewEmailVaildateCode(email);

        if (resultMessageStruct.getCode() == 500)
            throw new CustomMessageException(resultMessageStruct.getMessage());
        if (resultMessageStruct.getCode() != 200)
            throw new CustomException(UserExceptionEnum.getEnumByCode(resultMessageStruct.getCode()));
    }

    @PostMapping("modifyNewEmail")
    public void modifyNewEmail(String email, String code, HttpServletRequest request) throws Exception {
        String accessToken = request.getHeader("accessToken");
        String userId = getUserIdByToken(accessToken);

        if (StringUtils.isEmpty(email))
            throw new CustomException(UserExceptionEnum.USER_EMAIL_IS_NULL);

        SysUser sysUser = new SysUser();
        sysUser.setEmail(email);
        SysUser exists = userCenterServiceClient.exists(sysUser).getData();
        if (Objects.nonNull(exists))
            throw new CustomException(UserExceptionEnum.EMAIL_BE_USED);


        RequestParameterDataStrcut<String, String, String> requestParameterDataStrcut = new RequestParameterDataStrcut();
        requestParameterDataStrcut.setData(email);
        requestParameterDataStrcut.setCode(code);
        requestParameterDataStrcut.setRequest(userId);

        ResultMessageStruct resultMessageStruct = validateCodeServiceClient.modifyNewEmail(requestParameterDataStrcut);

        if (resultMessageStruct.getCode() == 500)
            throw new CustomMessageException(resultMessageStruct.getMessage());
        if (resultMessageStruct.getCode() != 200)
            throw new CustomException(UserExceptionEnum.getEnumByCode(resultMessageStruct.getCode()));
    }

    private String getUserIdByToken(String accessToken) {
        Token token = tokenService.validate(accessToken).getData();
        return token.getUserId();
    }
}
